using System;
using System.Collections.Generic;
using Moq;
using NUnit.Framework;
using Tycho.Grammar;
using Tycho.Parser.Peg;

namespace Tycho.UnitTests.Grammar {
    [TestFixture]
    public class NonTerminalRuleCompilerSpecification {
        [Test]
        public void ShouldUseCreatedCaptureCounterToCompileRule () {
            var ruleCompiler = new Mock<IRuleCompiler> ();
            ITerm term = new Mock<ITerm> ().Object;
            var context = new ProductionCompilerContext (null, null, null, null);

            IRule rule = new Mock<IRule> ().Object;

            var captureCounter = new FakeCaptureCounter ();

            var captures = new[] {"x"};
            var firstCapture = "first";
            var lastCapture = "last";

            ruleCompiler.Setup (r => r.Compile (term, context, captureCounter))
                .Returns (rule)
                .Callback (() => {
                               captureCounter.MultipleCaptures = captures;
                               captureCounter.FirstCapture = firstCapture;
                               captureCounter.LastCapture = lastCapture;
                           });

            var compiler = new NonTerminalRuleCompiler (ruleCompiler.Object, () => captureCounter);
            var ruleCaptures = compiler.Compile (term, context);
            Assert.That (ruleCaptures.Rule, Is.SameAs (rule));
            Assert.That (ruleCaptures.MultipleCaptures, Is.SameAs (captures));
            Assert.That (ruleCaptures.FirstCapture, Is.SameAs (firstCapture));
            Assert.That (ruleCaptures.LastCapture, Is.SameAs (lastCapture));
        }

        class FakeCaptureCounter : ICaptureCounter {
            public void Add (string captureName) {
            }

            public IEnumerable<string> MultipleCaptures { get; set; }

            public ICaptureCounter CreateMultipleCaptureScope () {
                return this;
            }

            public string FirstCapture { get; set; }

            public string LastCapture { get; set; }
        }
    }
}